
class Integrator {

  final float DAMPING = .45f;
  final float ATTRACTION = .2f;

  float value;
  float vel;
  float accel;
  float force;
  float mass = 1;

  float damping = DAMPING;
  float attraction = ATTRACTION;
  boolean targeting;
  float target;
  
  float framesPerSec = 60;
  float secPerTransition = 2.0;
  float rateOfChange;


  Integrator() { }


  Integrator(float value) {
    this.value = value;
    target = value;
  }


  Integrator(float value, float damping, float attraction) {
    this.value = value;
    this.damping = damping;
    this.attraction = attraction;
    target = value;
  }


  void set(float v) {
    value = v;
  }


  void update() {
    if(! targeting ){
      return;
    }
    if (targeting) {
      force += attraction * (target - value);      
    }
    if( abs(target - value ) < 1 ){
      value = target;
      targeting = false;
    }
    accel = force / mass;
    vel = (vel + accel) * damping;
    value += vel;
    //if( value < 0 ){
      //value = 0;
    //}

    force = 0;
  }
  
  void update2(){
    if( !targeting ){
      return;
    }
    if( targeting){
      value += (rateOfChange);
      rateOfChange= rateOfChange*1.05;
    }
    if( abs( target-value) < 2){
      value = target;
      targeting = false;
    }
  }


  void target(float t) {
    targeting = true;
    target = t;
  }
  
  
  void target2(float t){
    //println("target");
    targeting = true;
    target = t;
    rateOfChange = (target - value)/(framesPerSec*secPerTransition);
    //println( "rateOfChange = "+ rateOfChange);
    
  }


  void noTarget() {
    targeting = false;
  }
  
  boolean isTargeting(){
    return targeting;
  }
}

